package com.msunsoft.business.dictionary.lucence.impl;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.msunsoft.business.dictionary.lucence.LuceneContentInterface;
import com.msunsoft.business.dictionary.mybatis.model.DrugCompareCenterEntity;
import com.msunsoft.common.web.RealPathResolver;

public class LuceneDrugCompareService implements LuceneContentInterface<T> {

    private Logger                  logger    = LoggerFactory.getLogger (LuceneDrugCompareService.class);
    private String                  indexPath = "F:/lucene/dic/drugdictionary";
    @Autowired
    private RealPathResolver        realPathResolver;
    @Autowired
    private DrugCompareCenterMapper drugCompareCenterMapper;
    private Analyzer                analyzer  = new IKAnalyzer ();

    /**
     * Lucene文档，创建，更新并保存到Lucene文件系统中
     * 
     * @param item
     * @return
     * @throws IOException
     */
    public Integer createIndex(DrugCompareCenterEntity item) throws IOException{
        Directory dir = new SimpleFSDirectory (new File (indexPath));
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig (Version.LUCENE_35,analyzer);
        IndexWriter indexWriter = new IndexWriter (dir,indexWriterConfig);
        try {
            indexWriter.addDocument (LuceneDrugCompareItem.createDocument (item));
        } finally {
            indexWriter.close ();
        }
        return null;
    }

    /**
     * Description：按照ID进行索引
     * 
     * @author dennisit@163.com Apr 3, 2013
     * @param id
     */
    public void delete(DrugCompareCenterEntity item){
        try {
            Directory dir = new SimpleFSDirectory (new File (indexPath));
            IndexWriterConfig indexWriterConfig = new IndexWriterConfig (Version.LUCENE_35,analyzer);
            IndexWriter indexWriter = new IndexWriter (dir,indexWriterConfig);
            Term term = new Term (LuceneDrugCompareItem.FIELDS.ID.toString (),String.valueOf (item.getId ()));
            indexWriter.deleteDocuments (term);
            indexWriter.close ();
        } catch (Exception e) {
            e.printStackTrace ();
        }
    }

    /**
     * 删除全部索引
     */
    public void deleteAll(){
        try {
            Directory dir = new SimpleFSDirectory (new File (indexPath));
            boolean exist = IndexReader.indexExists (dir);
            if (exist) {
                long startTime = System.currentTimeMillis ();
                IndexWriterConfig indexWriterConfig = new IndexWriterConfig (Version.LUCENE_35,analyzer);
                IndexWriter indexWriter = new IndexWriter (dir,indexWriterConfig);
                indexWriter.deleteAll ();
                indexWriter.close ();
                long endTime = System.currentTimeMillis ();
                logger.debug ("删除目录{}下数据标准字典已生成的索引数据。耗时【{}】毫秒...", indexPath, (endTime - startTime));
            }
        } catch (Exception e) {
            e.printStackTrace ();
        }
    }

    @Transactional(readOnly = true)
    public List<DrugCompareCenterEntity> searchList(DrugCompareCenterEntity item,int first,int max) throws IOException,InvalidTokenOffsetsException{
        if (first <= 0) {
            first = 0;
        }
        if (max <= 0) {
            max = 10;
        }
        Directory dir = new SimpleFSDirectory (new File (indexPath));
        // 创建索引搜索器,且只读
        IndexReader indexReader = IndexReader.open (dir);
        IndexSearcher indexSearcher = new IndexSearcher (indexReader);
        try {
            Query query = LuceneDrugCompareItem.createQuery (item, analyzer);
            TopDocs docs = indexSearcher.search (query, first + max);
            logger.info ("Lucene从数据标准字典索引【{}】中检索出数据结果总数为【{}】", indexPath, docs.totalHits);
            List<DrugCompareCenterEntity> bdDatasetDictonaryItems = LuceneDrugCompareItem.getResultList (indexSearcher, docs, query, analyzer);
            return bdDatasetDictonaryItems;
        } finally {
            indexSearcher.close ();
        }
    }

    public boolean loadAllDatasetDictionaryItem() throws IOException{
        boolean ret = false;
        deleteAll ();
        List<DrugCompareCenterEntity> itemList = drugCompareCenterMapper.selectDrugCompareLuceneItem (null);
        Directory dir = new SimpleFSDirectory (new File (indexPath));
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig (Version.LUCENE_35,analyzer);
        IndexWriter indexWriter = new IndexWriter (dir,indexWriterConfig);
        int successTotal = 0, failtrueTotal = 0;
        long startTime = System.currentTimeMillis ();
        if (itemList.size () > 0) try {
            try {
                for ( DrugCompareCenterEntity bdDatasetDictonaryItem : itemList ) {
                    indexWriter.addDocument (LuceneDrugCompareItem.createDocument (bdDatasetDictonaryItem));
                    successTotal++;
                }
            } catch (IOException e) {
                failtrueTotal++;
                e.printStackTrace ();
            }

        } finally {
            indexWriter.close ();
        }
        long endTime = System.currentTimeMillis ();
        logger.info ("加载数据标准字典完毕，导入成功数据【{}】条，导入失败数据【{}】条。耗时【{}】毫秒...", new String[] { String.valueOf (successTotal), String.valueOf (failtrueTotal), String.valueOf ((endTime - startTime)) });
        if (failtrueTotal > 0) ret = false;
        return ret;
    }

}
